package edu.co.gap.webservices;

import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import static edu.co.gap.util.FileHelper.loadIplImage;
import static edu.co.gap.util.FileHelper.writeFile;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Map;

import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.cpp.opencv_objdetect;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

import edu.co.gap.persistence.MongoDBHelper;
import edu.co.gap.recognition.EigenFace;
import edu.co.gap.util.FileHelper;
import edu.co.gap.world.Person;
/**
 * @author David
 * 
 */
public class WebServices {

	public static final String INPUT_IMAGE_NAME = "input";
	public static final String IP_HOST = "127.0.0.1";
	public static final String DATABASE_NAME = "GAP";
	public static final String COLLECTION_NAME = "GAP";
	public static final String COLLECTION_PERSONS = "PERSON";
	
	public static final String NAMESPACE_IMAGES = "IMAGES";
	public static final String NAMESPACE_IMAGES_REAL = "MUNDO";
//	public static final String NAMESPACE_IMAGES = "MUNDO";
	public static final String DATABASE_IMAGE_DATATYPE = "pgm";
	public static final String DATABASE_IMAGE_DATATYPE_REAL = "pgm";
	public static final String GAP_STORING=System.getenv("GAP_STORING");
//	public static final String GAP_STORING="";
	
	public WebServices() {
		 // Preload the opencv_objdetect module to work around a known bug.
        Loader.load(opencv_objdetect.class);
        Loader.load(com.googlecode.javacv.cpp.opencv_highgui.class);
	}

	
	public String hello(){
		
		return "q mas";
	}
	/**
	 * 
	 * <p>This is a web services action, it takes a images in bytes corresponding
	 * to some person and returns the person object or a unknown person object</p>
	 * 
	 * @param byte[] array of bits representing an image
	 * 
	 * @return object representing the person in image
	 */
	public String getBytes(byte[] bImage) {

		String response = null;

		Person person=null;
		
		System.out.println("Entering in getBytes");

		try {

			String fileInputPath=GAP_STORING.concat("/IMAGES/")
				.concat(INPUT_IMAGE_NAME).concat(".jpg");
			
			//storing input image
			writeFile(fileInputPath, bImage);
			if (true) {
				//getting the image in IplImage format, in black and white (grayscale)
				
				IplImage inputImage=loadIplImage(fileInputPath, com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE);
//				IplImage inputImage=cvLoadImage(fileInputPath, com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE,1,1);
//				IplImage inputImage=cvRe
				//instace of helping class of mongo
//				MongoDBHelper mongoH=new MongoDBHelper(DATABASE_NAME,NAMESPACE_IMAGES,IP_HOST);
				MongoDBHelper mongoH=new MongoDBHelper(DATABASE_NAME,NAMESPACE_IMAGES_REAL,IP_HOST);
				
				//getting all images from mongo collection_name
//				IplImage[] images=mongoH.getAllImagesCollection(DATABASE_IMAGE_DATATYPE);
				IplImage[] images=mongoH.getAllImagesCollection(DATABASE_IMAGE_DATATYPE_REAL);
				
				Map<Integer, String> map=mongoH.map;
				
				EigenFace eigenface=new EigenFace(images);
				
				//debug
//				inputImage=loadIplImage("C:/programacion/java/workspace/android/Servidor GAP/images/Consuelo/1.jpg", com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE);
				int indexPerson=eigenface.recognize(inputImage);
				
				if (indexPerson==-1) {
					person=Person.UNKNOWN;
				}
				else{
					String id=""+map.get(indexPerson);
					String name=(String)mongoH.getItem(COLLECTION_PERSONS, id, "name");
					person=new Person(name);
					response=person.getName();
				}
				
				mongoH.close();
			}
			
			System.out.println("Exit from getBytes");

		} catch (Exception e) {
			response = e.getMessage();
			System.err.println("Something happend in getBytes method: "
					+ e.getCause());
		}

		return response;
	}

	/**
	 * 
	 * <p>This is a web services action, it takes a images in bytes corresponding
	 * to some person and returns the person object or a unknown person object</p>
	 * 
	 * @param byte[] array of bits representing an image
	 * 
	 * @return object representing the person in image
	 */
	public Person getBytes2(byte[] bImage) {

		Person person = null;

		System.out.println("Entering in getBytes");

		try {

			OutputStream out = new FileOutputStream("%GAP_STORING%/IMAGES/"
					.concat(INPUT_IMAGE_NAME).concat(".jpg"));
			out.write(bImage);
			out.close();

			System.out.println("Exit from getBytes");

		} catch (Exception e) {
			System.err.println("Something happend in getBytes method: "
					+ e.getCause());
		}

		return person;
	}
	
 
	public static void main(String[] args) {
		WebServices w=new WebServices();
		try {
			w.getBytes(FileHelper.LoadImageInBytes("C:/Users/David/Documents/IMAGES/input.jpg"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
